package cn.com.tianpeidong.restaurantadmin.common.exception;

import cn.com.tianpeidong.restaurantadmin.common.constant.ErrorResponse;
import cn.com.tianpeidong.restaurantadmin.common.constant.PlatformError;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.shiro.authz.UnauthenticatedException;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;

/**
 * @author tianpeidong
 * @version 2019.01.13
 */
@ControllerAdvice(annotations = RestController.class)
public class DefaultApiExceptionHandler {

    private static final Logger LOGGER = LogManager.getLogger();

    @ExceptionHandler(value = Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public ErrorResponse defaultApiErrorHandler(HttpServletRequest request, Exception e) throws Exception {
        // If the exception is annotated with @ResponseStatus rethrow it and let
        // the framework handle it - like the OrderNotFoundException example
        // at the start of this post.
        // AnnotationUtils is a Spring Framework utility class.
        if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus
                .class) != null) {
            throw e;
        }

        // Otherwise setup and send the userCredentialService to a default error message.
        ErrorResponse response = ErrorResponse.code(PlatformError.INTERNAL_ERROR
        ).build();
        response.msg = e.getMessage();
        LOGGER.error("Unhandled exception:" + request.getRequestURI(), e);
        return response;
    }

//    @ExceptionHandler(value = NullPointerException.class)
//    @ResponseStatus(HttpStatus.BAD_REQUEST)
//    @ResponseBody
//    public ErrorResponse NullPointerExceptionHandler() {
//        return ErrorResponse.code(PlatformError.BAD_REQUEST).build();
//    }

    /**
     * 未授权的服务统一为404，返回403有一点此地无银三百两的意思
     * @return
     */
    @ExceptionHandler(value = UnauthorizedException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    @ResponseBody
    public ErrorResponse unauthorizedExceptionHandler() {
        return ErrorResponse.code(PlatformError.RESOURCES_NOT_EXIST).build();
    }

    /**
     * 未登录
     * @return
     */
    @ExceptionHandler(value = UnauthenticatedException.class)
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    @ResponseBody
    public ErrorResponse unAuthencatedExceptionHandler() {
        return ErrorResponse.code(PlatformError.UNAUTHENCATED).build();
    }

    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(BusinessException.class)
    @ResponseBody
    public ErrorResponse handleBussinessException(
            BusinessException ex) {
        return ErrorResponse.code(PlatformError.BAD_REQUEST).buildWithCustomMsg(ex.getMessage());
    }

    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public ErrorResponse handleValidationExceptions(
            MethodArgumentNotValidException ex) {
        String errMsg = ex.getBindingResult().getAllErrors().get(0).getDefaultMessage();
        return ErrorResponse.code(PlatformError.PARAMETER_ERROR).buildWithCustomMsg(errMsg);
    }

    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(MissingServletRequestParameterException.class)
    @ResponseBody
    public ErrorResponse handleMissingRequestParamException(
            MissingServletRequestParameterException ex) {
        String errMsg = ex.getMessage();
        return ErrorResponse.code(PlatformError.BAD_REQUEST).buildWithCustomMsg(errMsg);
    }
}
